<?php
declare (strict_types=1);

namespace app\service;

use think\facade\Cache;
use app\model\Admin;

class TokenService
{
    private function getKey($user_id)
    {
        return 'token_' . $user_id;
    }

    private function getToken($header_token, $user_id)
    {
        return $header_token . "_" . $user_id;
    }

    public static function createToken($user_id)
    {
        return base64_encode(md5(rand(1000, 9999) . time())) . "_" . $user_id;
    }

    public function updateToken($user_id)
    {
        $token = self::createToken($user_id);
        $return = Admin::update(['token' => $token], ['id' => $user_id]);
        if (!$return) {
            throw new \Exception("TokenService updateToken error");
        }
        $key = $this->getKey($user_id);

        Cache::delete($key);
        return $token;
    }

    public function getAdminByToken($user_id, $token)
    {
        $key = $this->getKey($user_id);

        if (Cache::get($key)) {
            return Cache::get($key);
        }

        $admin = Admin::where(['token' => $this->getToken($token, $user_id)])->whereNull('deleted_at')->find();

        if (!$admin) {
            return false;
        }

        Cache::set($key, $admin);

        return $admin;
    }

    public function delToken($user_id, $token)
    {
        $return = Admin::update(['token' => ''], ['token' => $this->getToken($token,$user_id)]);

        if (!$return) {
            throw new \Exception("TokenService delToken error");
        }

        $key = $this->getKey($user_id);

        return Cache::delete($key);
    }

    public function setLastOperationTime()
    {
        $redis = RedisService::getRedis();
        $key = 'admin:' . AuthService::userId();
        $redis->hSet($key, 'last_operation_time', time());
    }

    public function checkVaildTime($user_id,$token)
    {
        $redis = RedisService::getRedis();
        $key = 'admin:' . AuthService::userId();
        $last_operation_time = $redis->hGet($key, 'last_operation_time');

        if ($last_operation_time && time() - $last_operation_time > 86400 * 7) {
            $this->delToken($user_id, $token);
            $redis->hDel($key, 'last_operation_time');
            return false;
        }

        $this->setLastOperationTime();

        return true;
    }
}